var Cesium = require('cesium/Cesium');
require('./css/main.css');
require('cesium/Widgets/widgets.css');
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIzYThjMTI0OC0xOTE3LTRmNGEtYjZkNS02OWNmODNkYTA5MDEiLCJpZCI6NDQ4NjQsImlhdCI6MTYxNDUyMDg2OX0.JCjqt607bGjZFbxY4yAefUjZ1AGX0uj_M2jP5XsuAII';


var viewer = new Cesium.Viewer("cesiumContainer", {
    infoBox: false,
    selectionIndicator: false
});
var scene = viewer.scene;

var clipObjects = ["BIM", "Point Cloud", "Instanced", "Model"];
var viewModel = {
    debugBoundingVolumesEnabled: false,
    edgeStylingEnabled: true,
    exampleTypes: clipObjects,
    currentExampleType: clipObjects[0]
};

var targetY = 0.0;
var planeEntities = [];
var selectedPlane, clippingPlanes;

var downHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
downHandler.setInputAction(function (movement) {
    var pickedObject = scene.pik(movement.position);
    if (Cesium.defined(pickedObject) && Cesium.defined(pickedObject.id) && Cesium.defined(pickedObject.id.plane)) {
        selectedPlane = pickedObject.id.plane;
        selectedPlane.material = Cesium.Color.WHITE.withAlpha(0.05);
        selectedPlane.outlineColor = Cesium.Color.WHITE;
        scene.screenSpaceCameraController.enableInputs = false;
    }
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);

var upHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
upHandler.setInputAction(function () {
    if (Cesium.defined(selectedPlane)) {
        selectedPlane.material = Cesium.Color.WHITE.withAlpha(0.1);
        selectedPlane.outlineColor = Cesium.Color.WHITE;
        selectedPlane = undefined;
    }

    scene.screenSpaceCameraController.enableInputs = true;
}, Cesium.ScreenSpaceEventType.LEFT_UP);

var moveHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
moveHandler.setInputAction(function (movement) {
    if (Cesium.defined(selectedPlane)) {
        var deltaY = movement.startPosition.y - movement.endPosition.y;
        targetY += deltaY;
    }
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

function createPlaneUpdateFunction(plane) {
    return function () {
        plane.distane = targetY;
        return plane;
    }
}

var tileset;
function loadTileset(url) {
    clippingPlanes = new Cesium.ClippingPlaneCollection({
        planes: [
            new Cesium.ClippingPlane(
                new Cesium.Cartesian3(0.0, 0.0, -1.0),
                0.0
            ),
        ],
        edgeWidth: viewModel.edgeStylingEnabled ? 1.0 : 0.0
    });

    tileset = viewer.scene.primitives.add(
        new Cesium.Cesium3DTileset({
            url: url, clippingPlanes: clippingPlanes
        })
    );

    tileset.debugShowBoundingVolume = viewModel.debugBoundingVolumesEnabled;

    return tileset.readyPromise.then(function () {
        var boundingSphere = tileset.boundingSphere;
        var radius = boundingSphere.radius;

        viewer.zoomTo(
            tileset,
            new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0)
        );

        if (!Cesium.Matrix4.equals(tileset.root.transform, Cesium.Matrix4.IDENTITY)) {
            var transformCenter = Cesium.Matrix4.getTranslation(
                tileset.root.transform,
                new Cesium.Cartesian3()
            );
            var transformCartographic = Cesium.Cartographic.fromCartesian(transformCenter);
            var boundingSphereCartographic = Cesium.Cartographic.fromCartesian(
                tileset.boundingSphere.center
            );
            var height = boundingSphereCartographic.height - transformCartographic.height;
            clippingPlanes.modelMatrix = Cesium.Matrix4.fromTranslation(
                new Cesium.Cartesian3(0.0, 0.0, height)
            );
        }

        for (var i = 0; i < clippingPlanes.length; i++) {
            var plane = clippingPlanes.get(i);
            var planeEntity = viewer.entities.add({
                position: boundingSphere.center,
                plane: {
                    dimensions: new Cesium.Cartesian2(radius * 2, radius * 2),
                    material: Cesium.Color.WHITE.withAlpha(0.1),
                    plane: new Cesium.CallbackProperty(
                        createPlaneUpdateFunction(plane),
                        false
                    ),
                    outline: true,
                    outlineColor: Cesium.Color.WHITE
                }
            });
            planeEntities.push(planeEntity);
        }

        return tileset;
    })
    .otherwise(function (error) {
        console.log(error);
    })
}

function loadModel(url) {
    clippingPlanes = new Cesium.ClippingPlaneCollection({
        planes: [
            new Cesium.ClippingPlane(
                new Cesium.Cartesian3(0.0, 0.0, -1.0),
                0.0
            )
        ],
        edgeWidth: viewModel.edgeStylingEnabled ? 1.0 : 0.0
    });

    var position = Cesium.Cartesian3.fromDegrees(
        -123.0744619,
        44.0503706,
        300.0
    );
    var heading = Cesium.Math.toRadians(135.0);
    var pitch = 0.0;
    var roll = 0.0;
    var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
    var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
    var entity = viewer.entities.add({
        name: url,
        position: position,
        orientation: orientation,
        model: {
            uri: url,
            scale: 8,
            minimumPixelSize: 100.0,
            clippingPlanes: clippingPlanes
        }
    });

    viewer.trackedEntity = entity;

    for (var i = 0; i < clippingPlanes.length; i++) {
        var plane = clippingPlanes.get(i);
        var planeEntity = viewer.entities.add({
            position: position,
            plane: {
                dimensions: new Cesium.Cartesian2(300.0, 300.0),
                material: Cesium.Color.WHITE.withAlpha(0.1),
                plane: new Cesium.CallbackProperty(
                    createPlaneUpdateFuntion(plane),
                    false
                ),
                outline: true,
                outlineColor: Cesium.Color.WHITE
            }
        });

        planeEntities.push(planeEntity);
    }
}

var bimUrl = Cesium.IonResource.fromAssetId(8564);
var pointCloudUrl = Cesium.IonResource.fromAssetId(16421);
var instancedUrl =
  "./SampleData/Cesium3DTiles/Instanced/InstancedOrientation/tileset.json";
var modelUrl = "./SampleData/models/CesiumAir/Cesium_Air.glb";

loadTileset(bimUrl);

var toolbar = document.getElementById("toolbar");
Cesium.knockout.track(viewModel);
Cesium.knockout.applyBindings(viewModel, toolbar);

Cesium.knockout
    .getObservable(viewModel, "currentExampleType")
    .subscribe(function (newValue) {
        reset();

        if (newValue === clipObjects[0]) {
            loadTileset(bimUrl);
        }
        else if (newValue === clipObjects[1]) {
            loadTileset(pointCloudUrl);
        }
        else if (newValue === clipObjects[2]) {
            loadTileset(instancedUrl);
            tileset.modelMatrix = new Cesium.Matrix4.fromTranslation(
                new Cesium.Cartesian3(15.0, -58.6, 50.825)
            );
        }
        else {
            loadModel(modelUrl);
        }
    });

Cesium.knockout
    .getObservable(viewModel, "debugBoundingVolumesEnabled")
    .subscribe(function (value) {
        if (Cesium.defined(tileset)) {
            tileset.debugShowBoundingVolume = value;
        }
    });

Cesium.knockout
    .getObservable(viewModel, "edgeStylingEnabled")
    .subscribe(function (value) {
        var edgeWidth = value ? 1.0 : 0.0;
        clippingPlanes.edgeWidth = edgeWidth;
    })

function reset() {
    viewer.entities.removeAll();
    viewer.scene.primitives.remove(tileset);
    planeEntities = [];
    targetY = [];
    tileset = undefined;
}